﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GameViewer.Core
{
    /** Static definitions of error codes.
            @todo
                Add many more exception codes, since we want the user to be able
                to catch most of them.
        */
       public enum ExceptionCodes {
            ERR_CANNOT_WRITE_TO_FILE,
            ERR_INVALID_STATE,
            ERR_INVALIDPARAMS,
            ERR_RENDERINGAPI_ERROR,
            ERR_DUPLICATE_ITEM,
            ERR_ITEM_NOT_FOUND,
            ERR_FILE_NOT_FOUND,
            ERR_INTERNAL_ERROR,
            ERR_RT_ASSERTION_FAILED, 
			ERR_NOT_IMPLEMENTED
        };

    public class GameViewerException : Exception
    {
        protected string mType;
        public GameViewerException(string message, string source)
            :base(message)
        {
            this.Source = source;
            LogManager.Instance.LogMessage(message, LogMessageLevel.LML_CRITICAL);
        }
    }

    public class ItemIdentityException : GameViewerException
    {
        public ItemIdentityException(string message, string source)
            : base(message, source)
        {
            mType = "ItemIdentityException";
        }
    }

    public class UnimplementedException : GameViewerException
    {
        public UnimplementedException(string message, string source)
            : base(message, source)
        {
            mType = "UnimplementedException";
        }
    }

    public class FileNotFoundException : GameViewerException
    {
        public FileNotFoundException(string message, string source)
            : base(message, source)
        {
            mType = "FileNotFoundException";
        }
    }

    public class IOException : GameViewerException
    {
        public IOException(string message, string source)
            : base(message, source)
        {
            mType = "IOException";
        }
    }

    public class InvalidStateException : GameViewerException
    {
        public InvalidStateException(string message, string source)
            : base(message, source)
        {
            mType = "InvalidStateException";
        }
    }

    public class InvalidParametersException : GameViewerException
    {
        public InvalidParametersException(string message, string source)
            : base(message, source)
        {
            mType = "InvalidParametersException";
        }
    }

    public class InternalErrorException : GameViewerException
    {
        public InternalErrorException(string message, string source)
            : base(message, source)
        {
            mType = "InternalErrorException";
        }
    }

    public class RenderingAPIException : GameViewerException
    {
        public RenderingAPIException(string message, string source)
            : base(message, source)
        {
            mType = "RenderingAPIException";
        }
    }

    public class RuntimeAssertionException : GameViewerException
    {
        public RuntimeAssertionException(string message, string source)
            : base(message, source)
        {
            mType = "RuntimeAssertionException";
        }
    }

    public class GameViewerExceptionFactory
    {
        //public static T Create<T>(string message, string source) where T: GameViewerException
        //{
        //    return (T)new GameViewerException(message);
        //}
        public static GameViewerException Create(ExceptionCodes code, string message, string source)
        {
            switch (code)
            {
                case ExceptionCodes.ERR_CANNOT_WRITE_TO_FILE:
                    return new IOException(message, source);
                case ExceptionCodes.ERR_DUPLICATE_ITEM:
                    return new ItemIdentityException(message, source);
                case ExceptionCodes.ERR_FILE_NOT_FOUND:
                    return new FileNotFoundException(message, source);
                case ExceptionCodes.ERR_INTERNAL_ERROR:
                    return new InternalErrorException(message, source);
                case ExceptionCodes.ERR_INVALID_STATE:
                    return new InvalidStateException(message, source);
                case ExceptionCodes.ERR_INVALIDPARAMS:
                    return new InvalidParametersException(message, source);
                case ExceptionCodes.ERR_ITEM_NOT_FOUND:
                    return new ItemIdentityException(message, source);
                case ExceptionCodes.ERR_NOT_IMPLEMENTED:
                    return new UnimplementedException(message, source);
                case ExceptionCodes.ERR_RENDERINGAPI_ERROR:
                    return new RenderingAPIException(message, source);
                case ExceptionCodes.ERR_RT_ASSERTION_FAILED:
                    return new RuntimeAssertionException(message, source);
                default:
                    return new GameViewerException(message, source);
            }
            return new GameViewerException(message, source);
        }
    }
}
